﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Utility.Persistence_Service
{
    public interface UnitOfWork : IDisposable
    {
        /// <summary>
        /// Rollbacked die aktive Transaktion bei Dispose und schließt die aktive Datenbank-Verbindung.
        /// </summary>
        void RollbackOnDispose();

        /// <summary>
        /// Commited oder Rollbacked die aktive Transaktion und schließt die aktive Datenbank-Verbindung.
        /// Anschließen wird eine neue Transaktion begonnen mit neuer Datenbank-Verbindung
        /// </summary>
        void Reset();

        /// <summary>
        /// Commited oder Rollbacked die aktive Transaktion.
        /// Anschließen wird eine neue Transaktion begonnen.
        /// </summary>
        void ResetTransactionOnly();

        /// <summary>
        /// Für individuelle Queries über Linq.
        /// </summary>
        /// <typeparam name="T">Objekt</typeparam>
        /// <returns>Linq.IQueryable</returns>
        IQueryable<T> Query<T>() where T : class;

        /// <summary>
        /// Gibt ein Objekt anhand des Primärschlüssels zurück.
        /// </summary>
        /// <typeparam name="T">Objekt</typeparam>
        /// <typeparam name="V">Primärschlüssel</typeparam>
        /// <param name="id">Konkreter Schlüssel</param>
        /// <returns>Gefundenes Objekt</returns>
        T FindById<T, V>(V id) where T : class;

        /// <summary>
        /// Speichert ein neues Objekt.
        /// </summary>
        /// <typeparam name="T">Objekt</typeparam>
        /// <param name="entity">Konkretes Objekt</param>
        /// <returns>Gespeichertes Objekt</returns>
        T Create<T>(T entity) where T : class;

        /// <summary>
        /// Speichert ein neues Objekt oder Updated ein existierendes Objekt.
        /// </summary>
        /// <typeparam name="T">Objekt</typeparam>
        /// <param name="entity">Konkretes Objekt</param>
        /// <returns>Gespeichertes Objekt</returns>
        T CreateOrUpdate<T>(T entity) where T : class;

        /// <summary>
        /// Updated ein existierendes Objekt.
        /// </summary>
        /// <typeparam name="T">Objekt</typeparam>
        /// <param name="entity">Konkretes Objekt</param>
        /// <returns>Geupdatetes Objekt</returns>
        T Update<T>(T entity) where T : class;

        /// <summary>
        /// Löscht ein existierendes Objekt.
        /// </summary>
        /// <typeparam name="T">Objekt</typeparam>
        /// <param name="entity">Konkretes Objekt</param>
        void Delete<T>(T entity) where T : class;

        /// <summary>
        /// Gibt alle Objekte eines Typs zurück.
        /// </summary>
        /// <typeparam name="T">Objekt-Typ</typeparam>
        /// <returns>Objekt-Liste</returns>
        IList<T> FindAll<T>() where T : class;
    }
}
